#include  <strings.h>
#include  <stdio.h>
#include  <sys/types.h>
#include  <sys/socket.h>
#include  <sys/stat.h>
#include  <netdb.h>
#include  <unistd.h>
#include  <cstdlib>
#include  <iostream>
#include  <sys/sendfile.h>
#include  <fcntl.h>
#include  <errno.h>
#include "gheaders.h"
#include "tcp_routines.h"

using namespace std;


/* ---------------------------------------------------------------*/
/**
 * 函数简介:   封装了TCP客户端连接服务器的例程
 *
 * 参数: host  主机域名或者IP
 * 参数: serv  主机端口号
 *
 * 返回值:     -1表示连接失败   0表示成功
 */
/* ---------------------------------------------------------------*/
int tcp_connect(const char *host, const char *serv)
{
        int				sockfd, n;
        struct addrinfo	hints, *res, *ressave;

        bzero(&hints, sizeof(struct addrinfo));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
                return -1;

        ressave = res;

        do {
                sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
                if (sockfd < 0)
                        continue;	/* ignore this one */

                if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
                        break;		/* success */

                close(sockfd);	/* ignore this one */
        } while ( (res = res->ai_next) != NULL);

        if (res == NULL)	/* errno set from final connect() */
                return -1;

        freeaddrinfo(ressave);

        return(sockfd);
}
/* end tcp_connect */

/*
 * We place the wrapper function here, not in wraplib.c, because some
 * XTI programs need to include wraplib.c, and it also defines
 * a Tcp_connect() function.
 */

int Tcp_connect(const char *host, const char *serv)
{
        return(tcp_connect(host, serv));
}

ssize_t readn(int fd, void *vptr, size_t n)
{
        size_t	nleft;
        ssize_t	nread;
        char	*ptr;

        ptr = (char*)vptr;
        nleft = n;
        while (nleft > 0)
        {
                if ( (nread = read(fd, ptr, nleft)) < 0)
                {
                        if (errno == EINTR)
                                nread = 0;		/* and call read() again */
                        else
                                return(-1);
                } else if (nread == 0)
                        break;				/* EOF */

                nleft -= nread;
                ptr   += nread;
        }
        return(n - nleft);		/* return >= 0 */
}

ssize_t writen(int fd, const void *vptr, size_t n)
{
        size_t		nleft;
        ssize_t		nwritten;
        const char	*ptr;

        ptr = (const char*)vptr;
        nleft = n;
        while (nleft > 0)
        {
                if ( (nwritten = write(fd, ptr, nleft)) <= 0)
                {
                        if (nwritten < 0 && errno == EINTR)
                                nwritten = 0;		/* and call write() again */
                        else
                                return(-1);			/* error */
                }

                nleft -= nwritten;
                ptr   += nwritten;
        }
        return(n);
}
/* end writen */

void Writen(int fd, void *ptr, size_t nbytes)
{
        if (writen(fd, ptr, nbytes) != nbytes)
        {
                perror("write");
                return;
        }
}

void file_copy(int des, int src)
{
        int res;
        char buf[BUF_SIZE];

        while( (res = readn(src,buf,BUF_SIZE)) > 0 )
        {
                Writen(des,buf,res);
        }

        if( res == 0 )
        {
                return;
        }
        else
        {
                perror("read");
                exit(-1);
        }
}
